package pl.jtb.ctl.tabory.ui.splashhandlers;

import org.eclipse.core.runtime.Status;
import org.eclipse.jface.dialogs.ErrorDialog;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.BusyIndicator;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.splash.AbstractSplashHandler;
import org.eclipse.wb.swt.SWTResourceManager;

import pl.jtb.ctl.tabory.ui.osgi.UiBundleActivator;
import pl.jtb.ctl.tabory.ui.security.SecurityUtils;

public class ApplicationSplashHandler extends AbstractSplashHandler {

    private final static int F_LABEL_HORIZONTAL_INDENT = 160;
    private final static int F_BUTTON_WIDTH_HINT = 80;
    private final static int F_TEXT_WIDTH_HINT = 160;
    private final static int F_COLUMN_COUNT = 3;
    private Composite fCompositeLogin;
    private Text fTextUsername;
    private Text fTextPassword;
    private Button fButtonOK;
    private Button fButtonCancel;
    private boolean fAuthenticated;

    public ApplicationSplashHandler() {
        fCompositeLogin = null;
        fTextUsername = null;
        fTextPassword = null;
        fButtonOK = null;
        fButtonCancel = null;
        fAuthenticated = false;
    }

    public void init(final Shell splash) {
        super.init(splash);
        configureUISplash();
        createUI();
        createUIListeners();
        splash.layout(true);
        fTextUsername.setFocus();
        doEventLoop();
    }

    private void doEventLoop() {
        Shell splash = getSplash();
        while (fAuthenticated == false) {
            if (splash.getDisplay().readAndDispatch() == false) {
                splash.getDisplay().sleep();
            }
        }
    }

    private void createUIListeners() {
        createUIListenersButtonOK();
        createUIListenersButtonCancel();
    }

    private void createUIListenersButtonCancel() {
        fButtonCancel.addSelectionListener(new SelectionAdapter() {
            public void widgetSelected(SelectionEvent e) {
                handleButtonCancelWidgetSelected();
            }
        });
    }

    private void handleButtonCancelWidgetSelected() {
        getSplash().getDisplay().close();
        System.exit(0);
    }

    private void createUIListenersButtonOK() {
        fButtonOK.addSelectionListener(new SelectionAdapter() {
            public void widgetSelected(SelectionEvent e) {
                try {
                    handleButtonOKWidgetSelected();
                } catch (Exception e1) {
                    fAuthenticated = false;
                }
            }
        });
    }

    private void handleButtonOKWidgetSelected() {
        BusyIndicator.showWhile(Display.getDefault(), new Runnable() {
            @Override
            public void run() {
                String username = fTextUsername.getText();
                String password = fTextPassword.getText();
                try {
                    fAuthenticated = SecurityUtils.logonUser(username, password);
                } catch (Exception e) {
                    fAuthenticated = false;
                    ErrorDialog dialog = new ErrorDialog(getSplash(), UiBundleActivator.getMessage("common.dialog.error.title"), e.getMessage(), new Status(1, "edytor", e.getMessage()), 1);
                    dialog.open();
                }
            }
        });
    }

    private void createUI() {
        createUICompositeLogin();
        createUICompositeBlank();
        createUILabelUserName();
        createUITextUserName();
        createUILabelPassword();
        createUITextPassword();
        createUILabelBlank();
        createUIButtonOK();
        createUIButtonCancel();
        fTextUsername.setText("admin");
        fTextPassword.setText("admin");
    }

    private void createUIButtonCancel() {
        fButtonCancel = new Button(fCompositeLogin, SWT.PUSH);
        fButtonCancel.setText(UiBundleActivator.getMessage("splash.label.cancel"));
        GridData data = new GridData(SWT.NONE, SWT.NONE, false, false);
        data.widthHint = F_BUTTON_WIDTH_HINT;
        data.verticalIndent = 10;
        fButtonCancel.setLayoutData(data);
    }

    private void createUIButtonOK() {
        fButtonOK = new Button(fCompositeLogin, SWT.PUSH);
        fButtonOK.setText(UiBundleActivator.getMessage("splash.label.logon"));
        GridData data = new GridData(SWT.NONE, SWT.NONE, false, false);
        data.widthHint = F_BUTTON_WIDTH_HINT;
        data.verticalIndent = 10;
        fButtonOK.setLayoutData(data);
    }

    private void createUILabelBlank() {
        Label label = new Label(fCompositeLogin, SWT.NONE);
        label.setVisible(false);
    }

    private void createUITextPassword() {
        int style = SWT.PASSWORD | SWT.BORDER;
        fTextPassword = new Text(fCompositeLogin, style);
        GridData data = new GridData(SWT.NONE, SWT.NONE, false, false);
        data.widthHint = F_TEXT_WIDTH_HINT;
        data.horizontalSpan = 2;
        fTextPassword.setLayoutData(data);
    }

    private void createUILabelPassword() {
        Label label = new Label(fCompositeLogin, SWT.NONE);
        label.setForeground(SWTResourceManager.getColor(SWT.COLOR_LIST_BACKGROUND));
        label.setText(UiBundleActivator.getMessage("splash.label.pass"));
        GridData data = new GridData();
        data.horizontalIndent = F_LABEL_HORIZONTAL_INDENT;
        label.setLayoutData(data);
    }

    private void createUITextUserName() {
        fTextUsername = new Text(fCompositeLogin, SWT.BORDER);
        GridData data = new GridData(SWT.NONE, SWT.NONE, false, false);
        data.widthHint = F_TEXT_WIDTH_HINT;
        data.horizontalSpan = 2;
        fTextUsername.setLayoutData(data);
    }

    private void createUILabelUserName() {
        Label label = new Label(fCompositeLogin, SWT.NONE);
        label.setForeground(SWTResourceManager.getColor(SWT.COLOR_LIST_BACKGROUND));
        label.setText(UiBundleActivator.getMessage("splash.label.user"));
        GridData data = new GridData();
        data.horizontalIndent = F_LABEL_HORIZONTAL_INDENT;
        label.setLayoutData(data);
    }

    private void createUICompositeBlank() {
        Composite spanner = new Composite(fCompositeLogin, SWT.NONE);
        GridData data = new GridData(SWT.FILL, SWT.FILL, true, true);
        data.horizontalSpan = F_COLUMN_COUNT;
        spanner.setLayoutData(data);
    }

    private void createUICompositeLogin() {
        fCompositeLogin = new Composite(getSplash(), SWT.BORDER);
        GridLayout layout = new GridLayout(F_COLUMN_COUNT, false);
        fCompositeLogin.setLayout(layout);
    }

    private void configureUISplash() {
        FillLayout layout = new FillLayout();
        getSplash().setLayout(layout);
        getSplash().setBackgroundMode(SWT.INHERIT_DEFAULT);
    }

}
